package com.yanqu.road.server.manger;

import com.yanqu.road.entity.enums.eChannelType;
import com.yanqu.road.entity.enums.eSexType;
import com.yanqu.road.logic.bussiness.config.NameBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.config.system.UserName;
import com.yanqu.road.entity.language.LanguageType;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class NameMgr extends TempMgr {

    private static Map<String, List<String>> surNameMap;

    private static Map<String, List<String>> nameMap;

    private static Map<String, List<String>> nameWMap;

    private static RandomHelper random = new RandomHelper();

    public static final int MAX_NICK_NAME_LENGTH = 16;

    public static final int DEFAULT_MAX_NICK_NAME_LENGTH = 12;

    public static final int MIN_NICK_NAME_LENGTH = 4;

    private static List<String> randomCharList = new ArrayList<>();

    public static final String FORBIDDEN_NICKNAME_PREFIX = "FORBIDDEN_NICKNAME_PREFIX";      //"违规昵称";

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean reloadConfig() {
        randomCharList = initRandomCharList();
        initUserName();
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static int getMaxNickNameLength(int channelId) {
        if (eChannelType.isNickNameMaxLengthChannel(channelId)) {
            return MAX_NICK_NAME_LENGTH;
        }
        return DEFAULT_MAX_NICK_NAME_LENGTH;
    }

    private void initUserName(){
        Map<String, List<String>> surNameTempMap = new ConcurrentHashMap<>();
        Map<String, List<String>> nameTempMap = new ConcurrentHashMap<>();
        Map<String, List<String>> nameWTempMap = new ConcurrentHashMap<>();
        List<UserName> userNameList = NameBussiness.getUserNameList();
        for (UserName userName : userNameList) {
            if (!StringUtils.isNullOrEmpty(userName.getSurname()) && !"0".equals(userName.getSurname())) {
                if(!surNameTempMap.containsKey(userName.getLanguage())){
                    surNameTempMap.put(userName.getLanguage(), new ArrayList<>());
                }
                surNameTempMap.get(userName.getLanguage()).add(userName.getSurname());
            }
            if (!StringUtils.isNullOrEmpty(userName.getName()) && !"0".equals(userName.getName())) {
                if(!nameTempMap.containsKey(userName.getLanguage())){
                    nameTempMap.put(userName.getLanguage(), new ArrayList<>());
                }
                nameTempMap.get(userName.getLanguage()).add(userName.getName());
            }
            if (!StringUtils.isNullOrEmpty(userName.getNameW()) && !"0".equals(userName.getNameW())) {
                if(!nameWTempMap.containsKey(userName.getLanguage())){
                    nameWTempMap.put(userName.getLanguage(), new ArrayList<>());
                }
                nameWTempMap.get(userName.getLanguage()).add(userName.getNameW());
            }
        }
        surNameMap = surNameTempMap;
        nameMap = nameTempMap;
        nameWMap = nameWTempMap;
    }

    public static String getRandomName(eSexType sex, String language) {
        String randomName;
        String surName = "";
        String name = "";
        List<String> surNameList;
        List<String> nameList;
        surNameList = surNameMap.get(language);
        if(null == surNameList){
            surNameList = surNameMap.get(LanguageType.LANGUAGE_DEFAULT);
        }
        switch (sex){
            case MALE:
                nameList = nameMap.get(language);
                if(null == nameList){
                    nameList = nameMap.get(LanguageType.LANGUAGE_DEFAULT);
                }
                break;
            case FEMALE:
                nameList = nameWMap.get(language);
                if(null == nameList){
                    nameList = nameWMap.get(LanguageType.LANGUAGE_DEFAULT);
                }
                break;
            default:
                return "";
        }

        boolean isForbid;
        int loopTimes = 0;
        do {
            isForbid = false;
            if (null != surNameList) {
                surName = surNameList.get(random.next(0, surNameList.size()));
            }

            if (null != nameList) {
                if (isSingleName()) {
                    name = nameList.get(random.next(0, nameList.size()));
                } else {
                    name = nameList.get(random.next(0, nameList.size())) + nameList.get(random.next(0, nameList.size()));
                }
            }
            randomName = surName + name;
            if(!StringUtils.isNullOrEmpty(randomName)) {
                if(Objects.equals(LanguageType.LANGUAGE_RU_RU, language)){//俄语诡异的取名规则，名字+#123
                    randomName = randomName + "#" + randomStr();
                }
                if (ForbiddenWordMgr.isNickNameForbidden(randomName)) {
                    isForbid = true;
                }
            }
            loopTimes++;
            if(loopTimes > 30){
                break;
            }
        }while (isForbid);
        return randomName;
    }

    /**
     * 随机名称 不检测敏感
     * @param sex
     * @param language
     * @return
     */

    public static String getRandomNameWithOutCheck(eSexType sex, String language) {
        String randomName;
        String surName = "";
        String name = "";
        List<String> surNameList;
        List<String> nameList;
        surNameList = surNameMap.get(language);
        if(null == surNameList){
            surNameList = surNameMap.get(LanguageType.LANGUAGE_DEFAULT);
        }
        switch (sex){
            case MALE:
                nameList = nameMap.get(language);
                if(null == nameList){
                    nameList = nameMap.get(LanguageType.LANGUAGE_DEFAULT);
                }
                break;
            case FEMALE:
                nameList = nameWMap.get(language);
                if(null == nameList){
                    nameList = nameWMap.get(LanguageType.LANGUAGE_DEFAULT);
                }
                break;
            default:
                return "";
        }


        if (null != surNameList) {
            surName = surNameList.get(random.next(0, surNameList.size()));
        }

        if (null != nameList) {
            if (isSingleName()) {
                name = nameList.get(random.next(0, nameList.size()));
            } else {
                name = nameList.get(random.next(0, nameList.size())) + nameList.get(random.next(0, nameList.size()));
            }
        }
        randomName = surName + name;
        if (!StringUtils.isNullOrEmpty(randomName)) {
            if (Objects.equals(LanguageType.LANGUAGE_RU_RU, language)) {//俄语诡异的取名规则，名字+#123
                randomName = randomName + "#" + randomStr();
            }

        }

        return randomName;
    }

    public static String randomStr(){
        int randomValue = random.next(0, 1000);
        return String.format("%03d", randomValue);
    }

    public static boolean isSingleName(){
        int randomValue = random.next(0, 1000);
        return GameConfig.RANDOM_NAME_PARAM > randomValue;
    }

    /**
     * 通用检查昵称（抄子嗣的）
     */
    public static int checkNickname(int channelId, String name) {
        if (StringUtils.isNullOrEmpty(name)) {
            return GameErrorCode.E_NAME_NO_EMPTY;
        }
        int nameLength = StringUtils.getStringLen(name);
        if (nameLength > NameMgr.getMaxNickNameLength(channelId) || nameLength < NameMgr.MIN_NICK_NAME_LENGTH) {
            return GameErrorCode.E_NAME_LENGTH_OVER;
        }
        //敏感字过滤
        if (ForbiddenWordMgr.isNickNameForbidden(name)) {
            return GameErrorCode.E_NAME_FORBIDDEN;
        }
        return 0;
    }

    public static Map<String, List<String>> getSurNameMap() {
        return surNameMap;
    }

    public static Map<String, List<String>> getNameMap() {
        return nameMap;
    }

    public static Map<String, List<String>> getNameWMap() {
        return nameWMap;
    }

    public static RandomHelper getRandom() {
        return random;
    }

    /**
    * 描述：初始化随机字符列表
    * 作者：zrq
    * 时间：2023/4/12
    * 参数：

    * 返回值：
    **/
    private static List<String> initRandomCharList(){
        List<String> dataList = new ArrayList<>();
        for(int i = 0; i < 10; i++){
            dataList.add("" + i);
        }
        for(int i = 0; i < 26; i++){
            char ch = (char) ('a' + i);
            dataList.add(String.valueOf(ch));
        }
        for(int i = 0; i < 26; i++){
            char ch = (char) ('A' + i);
            dataList.add(String.valueOf(ch));
        }
        return dataList;
    }

    /**
    * 描述：违规昵称
    * 作者：zrq
    * 时间：2023/4/12
    * 参数：

    * 返回值：
    **/
    public static String getForbiddenNickname(String prefix){
        StringBuilder result = new StringBuilder();
        if(!StringUtils.isNullOrEmpty(prefix)){
            result.append(prefix);
        }
        for(int i = 0; i < 6; i++){
            int randomIndex = random.next(0, randomCharList.size());
            String randomStr = "";
            if(randomIndex < randomCharList.size()){
                randomStr = randomCharList.get(randomIndex);
            }
            result.append(randomStr);
        }
        return result.toString();
    }
}
